<template>
  <div>
    <el-dialog
      title="上传文件"
      :visible.sync="dialogVisible"
      class="btwaDialog"
      width="600px"
      :before-close="closeDialog"
    >
      <div>
          <div style="padding-bottom: 10px;"> <span style="color: red;">*</span> 文件目录：{{ selectFolderDirectoryPath }} <el-button type="primary" @click="showFolderDialog">选择目录</el-button> </div>
          <div>
            <a-upload-dragger
              v-if="codeShow==false?true:false"
              name="file"
              accept=".mp4,.mov,.avi,.mpeg,.3gp,.mp3"
              :multiple="true"
              action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
              directory
              :before-upload="beforeUpload"
              :show-upload-list="false"
              :custom-request="(e)=>uploadFiles(e)"
              @change="handleChange"
            >
            <i class="el-icon-folder-opened" style="font-size: 50px;"></i>
              <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
              <div class="el-upload__tip" slot="tip">支持格式：mp4、mov、avi、mpeg、3gp、mp3；文件大小：＜500M</div>
            </a-upload-dragger>
            <a-upload-dragger
                    v-if="codeShow==true?true:false"
                    name="file"
                    accept=".mp4,.mov,.avi,.mpeg,.3gp,.mp3"
                    :multiple="true"
                    action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
                    directory
                    :before-upload="beforeUpload"
                    :show-upload-list="false"
                    :custom-request="(e)=>uploadsFiles(e)"
                    @change="handleChange"
            >
              <i class="el-icon-folder-opened" style="font-size: 50px;"></i>
              <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
              <div class="el-upload__tip" slot="tip">支持格式：mp4、mov、avi、mpeg、3gp、mp3；文件大小：＜500M</div>
            </a-upload-dragger>
          </div>
          <div class="" >
            <el-tabs v-model="fileStatus">
              <el-tab-pane :label="'等待中（'+wait_number+'）'" name="upload_waiting">
                <div v-if="videos.length > 0" style="margin-top: 5px">
                  <template v-for="(item, index) in videos">
                    <div class="plFileListView" v-if="item.uploading && (!item.uploadErr)"  :key="item.file.uid">
                      <div>{{ item.file.name || item.name }}</div>
                      <div style="width: 300px;white-space: nowrap;" v-if="item.percentage < 100" >
                        <el-progress :percentage="item.percentage"></el-progress>
                      </div>
                      <div class="plFileItemRemoveIcon" @click="handlePlFileRemove(item, 'await',index)"><i class="el-icon-circle-close"></i></div>
                    </div>
                  </template>
                </div>
                <el-empty v-if="!wait_number" description="暂无数据" :image-size="50"></el-empty>
              </el-tab-pane>
              <el-tab-pane :label="'上传成功（'+success_number+'）'" name="upload_success">
                <div v-if="videos.length > 0" style="margin-top: 5px">
                  <template v-for="(item, index) in videos">
                    <div class="plFileListView" v-if="(!item.uploading) && (!item.uploadErr)"  :key="item.file.uid">
                      <div>{{ item.file.name || item.name }}</div>
                      <div class="plFileItemRemoveIcon" @click="handlePlFileRemove(item, 'success')"><i class="el-icon-circle-close"></i></div>
                    </div>
                  </template>
                </div>
                <el-empty v-if="!success_number" description="暂无数据" :image-size="50"></el-empty>
              </el-tab-pane>
              <el-tab-pane :label="'上传失败（'+error_number+'）'" name="upload_fail">
                <div v-if="videos.length > 0" style="margin-top: 5px">
                  <template v-for="(item, index) in videos">
                    <div class="plFileListView" v-if="item.uploadErr"  :key="item.file.uid">
                      <div>{{ item.file.name || item.name }}</div>
                      <div class="plFileItemRemoveIcon" @click="handlePlFileRemove(item, 'error')"><i class="el-icon-circle-close"></i></div>
                    </div>
                  </template>
                </div>
                <el-empty v-if="!error_number" description="暂无数据" :image-size="50"></el-empty>
              </el-tab-pane>
            </el-tabs>
          </div>
      </div>

      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDialog()">取 消</el-button>
        <el-button type="primary" @click="onOk">开始上传</el-button>
      </span>
    </el-dialog>

    <el-dialog
      title="选择文件目录"
      :visible.sync="folderDirectoryVisible"
      class="btwaDialog"
      width="600px"
      :before-close="closeFolderDirectoryDialog"
    >
      <div v-if="folderDirectoryVisible">
        <el-tree
          :props="props"
          :load="loadNode"
          :node-key="'id'"
          :current-node-key="current_fold_id"
          :highlight-current="true"
          :expand-on-click-node="false"
          lazy
          @node-click="handleNodeClick"
        >
        </el-tree>
      </div>

      <span slot="footer" class="dialog-footer">
        <el-button @click="folderDirectoryVisible = false">取 消</el-button>
        <el-button type="primary" @click="onSelectFolderOk">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>

import {
  uploadMaterial,
  getFolders,
    companyOssUrls
} from "../../api";
import SparkMD5 from 'spark-md5';
const COS = require('cos-js-sdk-v5');
const cos = new COS({
  SecretId: 'AKIDhK6oW96L8mJbKvreiZCpXIw6h973lBKH',
  SecretKey: "rWzJROAlA5mNsBJH2auyxqYi2EAvYYMw",
  Protocol: "https:"
})
  export default {
    name: "UploadFileDialog",
    props: ['visible', 'propData','currentFoldId','currentNode','selectFolderDirectoryPaths'],
    data(){
      return {
          codeUrl:"",
          codeShow:"",
          videos: [],
          dialogVisible: false, // 最外层弹框控制显隐
          fileStatus: 'upload_waiting',
          wait_number: 0,
          success_number: 0,
          error_number: 0,
          folderDirectoryVisible: false,
          props: {
              label: 'name',
              children: 'name'
          },
        current_fold_id: null,// 当前的文件id
        current_node: null,// 当前选中的节点
        current_path_list: [], // 当前选中的节点路径list
          selectFolderDirectoryPath: '',// 当前选中的节点路径组装名
          uploadingFilesNumber: 0,
          waitUploadFiles: [],
      }
    },
      created(){
          // this.companyOssUrl();
      },
    mounted(){

    },
    watch:{
        currentFoldId(val){
            console.log(val);
            this.current_fold_id=val
        },
        selectFolderDirectoryPaths(val){
            this.selectFolderDirectoryPath =val
        },
        currentNode(val){
            console.log("val");
            this.current_node=val;
            console.log(this.current_node);
            this.current_path_list = [];
            this.getFolderPath(this.current_node);
            this.selectFolderDirectoryPath = this.current_path_list.join(' / ');
            console.log(this.selectFolderDirectoryPath);
        },
        visible(newVal, oldVal){
            console.log(newVal);
            this.dialogVisible = newVal;
            // this.companyOssUrl();
            // if(newVal){
            //   this.getOriginalityMaterialFileList();
            // }
        },
    },
    methods: {
        async companyOssUrl(){
            let res = await companyOssUrls().catch(e => e);
            if(res.code == 200 || res.msg == 'success'){
                this.codeShow= res.data.code;
                this.codeUrl=res.data.url;
            } else {
                this.$message.error(res.msg)
            }
            console.log(res);
        },
        batchUploadFileBesides100(){
            // 超过100后每有一个文件请求完成就进来判断
            let index = this.waitUploadFiles.findIndex(item=>item.uploading === false)
            if(index > -1){
                this.putFileToCos(this.waitUploadFiles[index].params, this.waitUploadFiles[index].md5name, null, true)
                this.$set(this.waitUploadFiles, index, {...this.waitUploadFiles[index], uploading: true})
            } else {
                //文件全部上传完毕
                console.log('全部上传完毕,清空');
                this.uploadingFilesNumber = 0;
                this.waitUploadFiles = [];
            }
        },
        batchUploadFileBesides1000(){
            // 超过100后每有一个文件请求完成就进来判断
            let index = this.waitUploadFiles.findIndex(item=>item.uploading === false)
            if(index > -1){
                this.putFilesToCos(this.waitUploadFiles[index].params, this.waitUploadFiles[index].md5name, null, true)
                this.$set(this.waitUploadFiles, index, {...this.waitUploadFiles[index], uploading: true})
            } else {
                //文件全部上传完毕
                // console.log('全部上传完毕,清空');
                this.uploadingFilesNumber = 0;
                this.waitUploadFiles = [];
            }
        },
      handlePlFileRemove(item, type,index){
          this.videos = this.videos.filter(value => value.file.uid != item.file.uid)
          if(type == 'await'){
              this.wait_number--;
          }else if(type == 'success') {
              this.success_number--
          } else {
              this.error_number--
          }
      },
      getFormat(name){
        let list = name.split('.');
        return list[list.length-1]
      },
      putFileToCos(params, md5name, type, nojudge){
          console.log("params");
          console.log(params);
          if(!nojudge){
          this.uploadingFilesNumber++
          if(this.uploadingFilesNumber >= 5){
            // 超过5个就不再上传，先添加进waitUploadFiles
            this.waitUploadFiles.push({
              params,
              md5name,
              uploading: false
            });
            return
          }
        }
        const vm = this;
        let index = this.videos.findIndex(item=>item.file.uid === params.file.uid)
        cos.putObject({
          Bucket: 'bdw-sh-1259268558',
          Region: 'ap-shanghai',
          Key: md5name,
          StorageClass: 'STANDARD',
          Body: params.file,
          onProgress: function(progressData) {
            if(index > -1){
              vm.$set(vm.videos, index, {...vm.videos[index], percentage: Math.round(progressData.percent * 100), uploading: true })
            }
            console.log(md5name+'文件上传进度：',JSON.stringify(progressData));
          }
        },(err, data) => {
          console.log(err || data);
          if(this.uploadingFilesNumber > 5) { this.batchUploadFileBesides100() }
          if(err){
            this.error_number++
            if(index > -1){
              vm.$set(vm.videos, index, {...vm.videos[index], md5name, uploadErr: true, uploading: false})
            }
            return;
          }
          if(data && data.statusCode === 200){
            this.success_number++;
            this.wait_number--;
            let url = `https:${data.Location}`
            if(index > -1){
              vm.$set(vm.videos, index, {...vm.videos[index], url, md5name, uploading: false})
            }
            console.log('url', url);
          }
        })
      },
        putFilesToCos(params, md5name, type, nojudge){
            // console.log(params);
            console.log("总共多少个视频 往数组里添加");
            console.log(this.videos);
            const vm = this;
            if(!nojudge){
                this.uploadingFilesNumber++
                if(this.uploadingFilesNumber >= 5){
                    // 超过5个就不再上传，先添加进waitUploadFiles
                    this.waitUploadFiles.push({
                        params,
                        md5name,
                        uploading: false
                    });
                    return
                }
            }
            if(vm.uploadingFilesNumber >= 4) { vm.batchUploadFileBesides1000() }
            console.log("uploadingFilesNumber"+vm.uploadingFilesNumber);
            console.log("wait_number"+vm.wait_number);
                let index = vm.videos.findIndex(item=>item.file.uid === params.file.uid)
                let formData = new FormData();
                // console.log(md5name);
                // console.log(params.file);
                var file = new File([params.file], md5name);
                // console.log("params.file");
                // console.log(params.file);
                // console.log(file);
                formData.append('file',file);
                // console.log(formData.get('file'));
                vm.axios.post(vm.codeUrl+"/v1/file_upload",formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    },
                    onUploadProgress: (progressData) => {
                        // console.log(progressData.loaded);
                        // console.log(progressData.total);
                        if(index > -1){
                            vm.$set(vm.videos, index, {...vm.videos[index], percentage: Math.round(progressData.loaded / progressData.total * 100), uploading: true })
                        }
                        console.log(md5name+'文件上传进度：',JSON.stringify(progressData));
                    },
                }).then((res) => {
                    console.log("文件返回");
                    console.log(res);

                    // console.log(res.code);
                    if(res && res.data.code === 0){
                        if(vm.videos.length!=this.success_number){
                            vm.success_number++;
                        }
                        if(vm.wait_number>0){
                            vm.wait_number--;
                        }
                        let url = res.data.file_url;
                        if(index > -1){
                            vm.$set(vm.videos, index, {...vm.videos[index], url, md5name, uploading: false})
                        }
                        // console.log('url', url);
                    }
                }).catch((err)=> {
                    console.log("上传失败");
                    console.log(err);
                    if(err){
                        vm.error_number++
                        if(index > -1){
                            vm.$set(vm.videos, index, {...vm.videos[index], md5name, uploadErr: true, uploading: false})
                        }
                        return;
                    }
                });



        },
        uploadsFiles(params, type){
            // console.log("params, type");
            // console.log(params);
            // console.log(type);
            if(params.file){
                // console.log('file',params.file);
                let fileObj = {
                    uploading: true,
                    uploadErr: false,
                    percentage: 0,
                    file: params.file,
                    url: '',
                    uid: params.file.uid,
                    name: params.file.name
                }
                // console.log("fileObj");
                // console.log(fileObj);
                this.wait_number++
                const fileFormat = this.getFormat(params.file.name)
                const isL200M = params.file.size / 1024 / 1024 < 200;
                // md5操作
                if(isL200M){
                    // 小文件
                    const fileReader = new FileReader();
                    fileReader.readAsBinaryString(params.file);
                    fileReader.onload = e => {
                        const md5 = SparkMD5.hashBinary(e.target.result);
                        const md5name = md5 + '.' + fileFormat;
                        // console.log('小文件MD5name', md5name);
                        this.videos.push(fileObj)
                        this.putFilesToCos(params, md5name, type)
                    }
                } else {
                    // 大文件
                    const sliceLength = 10;
                    const chunkSize = Math.ceil(params.file.size / sliceLength);
                    const fileReader = new FileReader();
                    const md5 = new SparkMD5();
                    let index = 0;
                    const loadFile = () => {
                        const slice = params.file.slice(index, index + chunkSize);
                        fileReader.readAsBinaryString(slice);
                    }
                    loadFile();
                    fileReader.onload = e => {
                        md5.appendBinary(e.target.result);
                        if(index < params.file.size){
                            index += chunkSize;
                            loadFile();
                        } else {
                            const md5name = md5.end() + '.' + fileFormat;
                            // console.log('大文件MD5name', md5name);
                            this.videos.push(fileObj)
                            this.putFilesToCos(params, md5name, type)
                        }
                    }
                }
            }
        },
      uploadFiles(params, type){
        if(params.file){
          console.log('file',params.file);
          let fileObj = {
            uploading: true,
            uploadErr: false,
            percentage: 0,
            file: params.file,
            url: '',
            uid: params.file.uid,
            name: params.file.name
          }
          this.wait_number++
          const fileFormat = this.getFormat(params.file.name)
          const isL200M = params.file.size / 1024 / 1024 < 200;
          // md5操作
          if(isL200M){
            // 小文件
            const fileReader = new FileReader();
            fileReader.readAsBinaryString(params.file);
            fileReader.onload = e => {
              const md5 = SparkMD5.hashBinary(e.target.result);
              const md5name = md5 + '.' + fileFormat;
              console.log('小文件MD5name', md5name);
              this.videos.push(fileObj)
              this.putFileToCos(params, md5name, type)
            }
          } else {
            // 大文件
            const sliceLength = 10;
            const chunkSize = Math.ceil(params.file.size / sliceLength);
            const fileReader = new FileReader();
            const md5 = new SparkMD5();
            let index = 0;
            const loadFile = () => {
              const slice = params.file.slice(index, index + chunkSize);
              fileReader.readAsBinaryString(slice);
            }
            loadFile();
            fileReader.onload = e => {
              md5.appendBinary(e.target.result);
              if(index < params.file.size){
                index += chunkSize;
                loadFile();
              } else {
                const md5name = md5.end() + '.' + fileFormat;
                console.log('大文件MD5name', md5name);
                this.videos.push(fileObj)
                this.putFileToCos(params, md5name, type)
              }
            }
          }
        }
      },
      beforeUpload(file, fileList){
        const isType = ['video/mp4','video/mov','video/avi','video/mpeg','video/3gp','audio/mpeg'].indexOf(file.type)
        if(isType < 0){
          this.$message.error('不支持的文件格式')
          return false;
        }
        return true;
      },
      handleChange(value) {
        // console.log(value);
      },
      resetData() {
        this.videos = [];
        this.wait_number = 0;
        this.success_number = 0;
        this.error_number = 0;
        this.uploadingFilesNumber = 0;
        this.waitUploadFiles = [];
      },
      closeDialog(done) {
        this.dialogVisible = false;
        this.$emit("changeVisible", false)
        if(done){
          done();
        }
      },
      async onOk() {
        let { videos, current_fold_id } = this;
        if(!current_fold_id){
          return this.$message.error('请选择上传视频的文件夹目录')
        }
        if(videos.length == 0){
          return this.$message.error('请上传视频')
        }
        if(this.wait_number>0){
            return this.$message.error('请等待视频全部上传完在上传')
        }
          console.log(this.videos);
        if(this.codeShow==true){
            let files = this.videos.map((item, index) => {
                return {
                    url: this.codeUrl+'/'+item.md5name,
                    name: item.file.name || item.name
                }
            });

            let params = {
                folder_id: this.current_fold_id,
                files
            }
            console.log(params);
                let res = await uploadMaterial(params).catch(e => e)
        if(res.code == 200 || res.msg == 'success') {
          this.$message.success("上传成功")
          this.dialogVisible = false;
          this.$emit("changeVisible", false)
          this.resetData()
        } else {
          this.$message.error(res.msg)
        }
        }else{
            let files = this.videos.map((item, index) => {
                return {
                    url: item.md5name,
                    name: item.file.name || item.name
                }
            })

            let params = {
                folder_id: this.current_fold_id,
                files
            }
            console.log(params);
                let res = await uploadMaterial(params).catch(e => e)
        if(res.code == 200 || res.msg == 'success') {
          this.$message.success("上传成功")
          this.dialogVisible = false;
          this.$emit("changeVisible", false)
          this.resetData()
        } else {
          this.$message.error(res.msg)
        }
        }



      },


      getFolderPath(currentNode,) {
        if(currentNode.parent.data){
          this.getFolderPath(currentNode.parent)
          this.current_path_list.push(currentNode.data.name)
        } else {
          this.current_path_list.push(currentNode.data.name)
        }
      },
      onSelectFolderOk() {
        if(!this.current_fold_id){
          return this.$message.error('请选择文件目录')
        }
        this.current_path_list = [];
        this.getFolderPath(this.current_node)
        this.selectFolderDirectoryPath = this.current_path_list.join(' / ');
        this.folderDirectoryVisible = false
      },
      handleNodeClick(data, node, myself) {
        console.log(data, node, myself, 'handleNodeClick');
        if(data.id != this.current_fold_id){
          this.current_fold_id = data.id;
          this.current_node = node;
        }
      },
      async loadNode(node, resolve) {
        if (node.level >= 0 && node.level < 3) {// 限制最多3级
          console.log('node',node);
          let list = await this.getFolders(node.data ? node.data.id : 0)
          // let list = await this.getFolders(0)
          return resolve(list || []);
        }
        if (node.level >= 3) {
          return resolve([]);
        }
      },
      async getFolders(folder_id) {
        let res = await getFolders({parent_id: folder_id}).catch(e => e)
        if(res.code == 200 || res.msg == 'success'){
          return res.data.list
        } else {
          this.$message.error('获取文件夹目录失败' + res.msg)
        }
      },
      showFolderDialog() {
        this.folderDirectoryVisible = true;
        this.current_fold_id = null;
        this.current_node = null;
      },
      closeFolderDirectoryDialog(done) {
        this.folderDirectoryVisible = false;
        done();
      },
    },
  }
</script>

<style lang="scss" scoped>
.inputM {
    margin: 0 5px;
    width: 150px;
    white-space: nowrap;
}
.searchItem{
  padding: 0px 10px;
  .searchItemText{
    cursor: pointer;
    &:hover{
      color: "#409eff"
    }
  }
}
.actionItem{
  cursor: pointer;
  color: #409eff;
}
.plFileListView{
  display: flex;
  align-items: center;
  flex-direction: row;
  padding: 5px;
  border-radius: 4px;
  &:hover{
    background-color: #f5f7fa;
    .plFileItemRemoveIcon{
      cursor: pointer;
      visibility: visible;
    }
  }
  .plFileItemRemoveIcon{
    visibility: hidden;
    margin-left: 5px;
    margin-right: 15px;
  }
}
</style>
